package com.yaoyong.codegenerator.ui;

import com.yaoyong.codegenerator.entity.Database;
import com.yaoyong.codegenerator.entity.Table;
import com.yaoyong.codegenerator.properties.PathProperties;
import com.yaoyong.codegenerator.properties.ProjectProperties;
import com.yaoyong.codegenerator.utils.CodeUtil;
import com.yaoyong.codegenerator.utils.DbXmlUtil;
import org.dom4j.DocumentException;

import javax.swing.*;
import javax.swing.border.EmptyBorder;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.io.File;
import java.io.IOException;
import java.util.List;
import java.util.Map;

public class CodeWindow extends JFrame {

    private JPanel contentPane;
    private JComboBox template;
    private JTextField xmlPath;
    private JTextField codePath;
    private JTextField project;
    private JTextField projectComment;
    private JTextField packageName;
    private JTextField author;
    private JTextField db;
    private JTextField username;
    private JTextField password;
    private JButton codeButton;

    private Database database;

    /**
     * Launch the application.
     */
    public static void main(String[] args) {
        EventQueue.invokeLater(() -> {
            try {
                CodeWindow frame = new CodeWindow();
                frame.setVisible(true);
            } catch (Exception e) {
                e.printStackTrace();
            }
        });
    }

    /**
     * Create the frame.
     */
    public CodeWindow() {
        addWindowListener(new WindowAdapter() {
            @Override
            public void windowOpened(WindowEvent e) {
                loadData();
            }

            @Override
            public void windowClosing(WindowEvent e) {
                releaseResource(e);
            }

            @Override
            public void windowClosed(WindowEvent e) {
                releaseResource(e);
            }
        });
        setTitle("私人定制代码生成器V1.0");
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setBounds(100, 100, 580, 550);
        contentPane = new JPanel();
        contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
        setContentPane(contentPane);
        contentPane.setLayout(null);

        JLabel label1 = new JLabel("模板");
        label1.setFont(new Font("微软雅黑", Font.PLAIN, 16));
        label1.setBounds(25, 25, 120, 25);
        contentPane.add(label1);

        template = new JComboBox();
        template.setModel(new DefaultComboBoxModel(new String[]{"-----  请   选   择   模   板 -----"}));
        template.setFont(new Font("微软雅黑", Font.PLAIN, 16));
        template.setBounds(155, 25, 255, 25);
        contentPane.add(template);

        JLabel label2 = new JLabel("映射文件路径");
        label2.setHorizontalAlignment(SwingConstants.LEFT);
        label2.setFont(new Font("微软雅黑", Font.PLAIN, 16));
        label2.setBounds(25, 65, 120, 25);
        contentPane.add(label2);

        xmlPath = new JTextField();
        xmlPath.setBounds(155, 65, 255, 25);
        xmlPath.setHorizontalAlignment(SwingConstants.LEFT);
        xmlPath.setFont(new Font("微软雅黑", Font.PLAIN, 16));
        contentPane.add(xmlPath);
        xmlPath.setColumns(10);

        JLabel label3 = new JLabel("代码生成路径");
        label3.setHorizontalAlignment(SwingConstants.LEFT);
        label3.setFont(new Font("微软雅黑", Font.PLAIN, 16));
        label3.setBounds(25, 105, 120, 25);
        contentPane.add(label3);

        codePath = new JTextField();
        codePath.setHorizontalAlignment(SwingConstants.LEFT);
        codePath.setFont(new Font("微软雅黑", Font.PLAIN, 16));
        codePath.setBounds(155, 105, 255, 25);
        contentPane.add(codePath);
        codePath.setColumns(10);

        JLabel label4 = new JLabel("项目英文名");
        label4.setHorizontalAlignment(SwingConstants.LEFT);
        label4.setFont(new Font("微软雅黑", Font.PLAIN, 16));
        label4.setBounds(25, 145, 120, 25);
        contentPane.add(label4);

        project = new JTextField();
        project.setBounds(155, 145, 255, 25);
        project.setHorizontalAlignment(SwingConstants.LEFT);
        project.setFont(new Font("微软雅黑", Font.PLAIN, 16));
        contentPane.add(project);
        project.setColumns(10);

        JLabel label5 = new JLabel("项目中文名");
        label5.setHorizontalAlignment(SwingConstants.LEFT);
        label5.setFont(new Font("微软雅黑", Font.PLAIN, 16));
        label5.setBounds(25, 185, 120, 25);
        contentPane.add(label5);

        projectComment = new JTextField();
        projectComment.setBounds(155, 185, 255, 25);
        projectComment.setHorizontalAlignment(SwingConstants.LEFT);
        projectComment.setFont(new Font("微软雅黑", Font.PLAIN, 16));
        contentPane.add(projectComment);
        projectComment.setColumns(10);

        JLabel label6 = new JLabel("包名");
        label6.setHorizontalAlignment(SwingConstants.LEFT);
        label6.setFont(new Font("微软雅黑", Font.PLAIN, 16));
        label6.setBounds(25, 225, 120, 25);
        contentPane.add(label6);

        packageName = new JTextField();
        packageName.setBounds(155, 225, 255, 25);
        packageName.setHorizontalAlignment(SwingConstants.LEFT);
        packageName.setFont(new Font("微软雅黑", Font.PLAIN, 16));
        contentPane.add(packageName);
        packageName.setColumns(10);

        JLabel label7 = new JLabel("作者");
        label7.setHorizontalAlignment(SwingConstants.LEFT);
        label7.setFont(new Font("微软雅黑", Font.PLAIN, 16));
        label7.setBounds(25, 265, 120, 25);
        contentPane.add(label7);

        author = new JTextField();
        author.setBounds(155, 265, 255, 25);
        author.setHorizontalAlignment(SwingConstants.LEFT);
        author.setFont(new Font("微软雅黑", Font.PLAIN, 16));
        contentPane.add(author);
        author.setColumns(10);

        JLabel label8 = new JLabel("数据库");
        label8.setHorizontalAlignment(SwingConstants.LEFT);
        label8.setFont(new Font("微软雅黑", Font.PLAIN, 16));
        label8.setBounds(25, 305, 120, 25);
        contentPane.add(label8);

        db = new JTextField();
        db.setBounds(155, 305, 255, 25);
        db.setHorizontalAlignment(SwingConstants.LEFT);
        db.setFont(new Font("微软雅黑", Font.PLAIN, 16));
        contentPane.add(db);
        db.setColumns(10);

        JLabel label9 = new JLabel("用户名");
        label9.setHorizontalAlignment(SwingConstants.LEFT);
        label9.setFont(new Font("微软雅黑", Font.PLAIN, 16));
        label9.setBounds(25, 345, 120, 25);
        contentPane.add(label9);

        username = new JTextField();
        username.setHorizontalAlignment(SwingConstants.LEFT);
        username.setFont(new Font("微软雅黑", Font.PLAIN, 16));
        username.setBounds(155, 345, 255, 25);
        contentPane.add(username);
        username.setColumns(10);

        JLabel label10 = new JLabel("密码");
        label10.setHorizontalAlignment(SwingConstants.LEFT);
        label10.setFont(new Font("微软雅黑", Font.PLAIN, 16));
        label10.setBounds(25, 385, 120, 25);
        contentPane.add(label10);

        password = new JTextField();
        password.setBounds(155, 385, 255, 25);
        password.setHorizontalAlignment(SwingConstants.LEFT);
        password.setFont(new Font("微软雅黑", Font.PLAIN, 16));
        contentPane.add(password);
        password.setColumns(10);

        codeButton = new JButton("生成代码");
        codeButton.addActionListener(e -> createCode(e));
        codeButton.setFont(new Font("微软雅黑", Font.PLAIN, 16));
        codeButton.setBounds(25, 450, 120, 25);
        contentPane.add(codeButton);

        JButton closeButton = new JButton("关闭");
        closeButton.addActionListener(e -> closeWindow());
        closeButton.setFont(new Font("微软雅黑", Font.PLAIN, 16));
        closeButton.setBounds(425, 450, 120, 25);
        contentPane.add(closeButton);

        JButton xmlPathButton = new JButton("选择");
        xmlPathButton.addActionListener(e -> showXmlPath(e));
        xmlPathButton.setFont(new Font("微软雅黑", Font.PLAIN, 16));
        xmlPathButton.setBounds(425, 65, 120, 25);
        contentPane.add(xmlPathButton);

        JButton codePathButton = new JButton("选择");
        codePathButton.addActionListener(e -> showCodePath(e));
        codePathButton.setFont(new Font("微软雅黑", Font.PLAIN, 16));
        codePathButton.setBounds(425, 105, 120, 25);
        contentPane.add(codePathButton);
    }

    /**
     * 点击生成代码
     *
     * @param e
     */
    private void createCode(ActionEvent e) {
        this.codeButton.setEnabled(false);
        this.codeButton.setText("代码生成中...");
        new MyCode().start();
    }

    /**
     * 展示代码生成路径
     *
     * @param e
     */
    private void showCodePath(ActionEvent e) {
        this.codePath.setText(selectPath("选择代码生成路径"));
    }

    /**
     * 展示映射文件路径
     *
     * @param e
     */
    private void showXmlPath(ActionEvent e) {
        this.xmlPath.setText(selectPath("选择映射文件路径"));
    }

    /**
     * 选择路径
     *
     * @param title
     */
    private String selectPath(String title) {
        JFileChooser jfc = new JFileChooser();
        jfc.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
        jfc.showDialog(new JLabel(), title);
        File file = jfc.getSelectedFile();
        if (file == null) {
            return null;
        }
        return file.getPath();
    }

    /**
     * 释放资源
     *
     * @param e
     */
    private void releaseResource(WindowEvent e) {
        closeWindow();
    }

    /**
     * 关闭窗口
     */
    private void closeWindow() {
        dispose();
        System.exit(0);
        System.out.println("释放资源");
    }

    /**
     * 添加模板类型到
     */
    private void loadData() {
        //设置为null则此窗口将置于屏幕的中央
        setLocationRelativeTo(null);
        // 获取当前文件夹下的模板目录下的所有文件夹
        // 设定为当前文件夹
        File directory = new File(new File("").getAbsolutePath() + File.separator + "codeTemplate");
        File[] listFiles = directory.listFiles();
        if (listFiles != null) {
            for (File f : listFiles) {
                if (f.isDirectory()) {
                    this.template.addItem(f.getName());
                }
            }
        }
        //映射文件默认位置
        this.xmlPath.setText(new File("").getAbsolutePath() + File.separator + "temp/db.xml");
        // 设置当前目录为默认代码生成目录
        this.codePath.setText(new File("").getAbsolutePath());

        // 默认按配置文件渲染窗体
        Map<String, Object> globalMap = DbXmlUtil.readGlobal();
        if (!globalMap.isEmpty()) {
            PathProperties path = (PathProperties) globalMap.get("path");
            ProjectProperties project = (ProjectProperties) globalMap.get("project");
            Database datasource = (Database) globalMap.get("datasource");
            this.project.setText(project.getName());
            this.projectComment.setText(project.getComment());
            this.packageName.setText(project.getPackageName());
            this.author.setText(project.getAuthor());
            this.db.setText(datasource.getName());
            this.username.setText(datasource.getUsername());
            this.password.setText(datasource.getPassword());
        }
    }

    /**
     * 渲染外部传递过来的参数
     *
     * @param database
     */
    public void showWindowInfo(Database database) {
        this.database = database;
        this.db.setText(database.getName());
        this.username.setText(database.getUsername());
        this.password.setText(database.getPassword());
    }


    class MyCode extends Thread {
        @Override
        public void run() {

            try {
                // 获取当前文件夹下的模板目录下的所有文件夹
                String basePath = new File("").getAbsolutePath() + File.separator + "codeTemplate" + File.separator + template.getSelectedItem();

                // 路径封装
                PathProperties path = new PathProperties();
                path.setBaseTemplatePath(basePath);
                path.setCodeGeneratorPath(codePath.getText());

                // 项目封装
                ProjectProperties project_ = new ProjectProperties();
                project_.setName(project.getText());
                project_.setComment(projectComment.getText());
                project_.setPackageName(packageName.getText());
                project_.setAuthor(author.getText());
                //
                project_.setGroupId(packageName.getText());
                project_.setArtifactId(project.getText());
                project_.setVersion("1.0.0");

                //数据库信息封装
                if (database == null) {
                    database = new Database();
                    database.setName(db.getText());
                    database.setUsername(username.getText());
                    database.setPassword(password.getText());
                    List<Table> tables = DbXmlUtil.read("temp/db.xml");
                    database.setTables(tables);
                }


                // 暂存变量
                DbXmlUtil.write(path, project_, database);
                // 生成代码
                CodeUtil.createCode(path, project_, database);
                JOptionPane.showMessageDialog(null, "代码生成成功", "提示", JOptionPane.DEFAULT_OPTION);
            } catch (DocumentException e) {
                e.printStackTrace();
                JOptionPane.showMessageDialog(null, e.getMessage(), "读取配置文件出错", JOptionPane.INFORMATION_MESSAGE);
            } catch (IOException e) {
                e.printStackTrace();
                JOptionPane.showMessageDialog(null, e.getMessage(), "请检查路径是否正确", JOptionPane.INFORMATION_MESSAGE);
            } catch (Exception e) {
                e.printStackTrace();
                JOptionPane.showMessageDialog(null, "发生错误" + e.getMessage(), "错误详情请查看error.log", JOptionPane.INFORMATION_MESSAGE);

            }


            codeButton.setEnabled(true);
            codeButton.setText("生成代码");
        }
    }
}
